home *** CD-ROM | disk | FTP | other *** search
/ Programming a Multiplayer FPS in DirectX / Programming a Multiplayer FPS in DirectX (Companion CD).iso / DirectX / dxsdk_oct2004.exe / dxsdk.exe / Samples / C++ / Direct3D / AntiAlias / AntiAlias.cpp next >
Encoding:
C/C++ Source or Header  |  2004-09-28  |  45.5 KB  |  1,112 lines

  1. //--------------------------------------------------------------------------------------
  2. // File: AntiAlias.cpp
  3. //
  4. // Multisampling attempts to reduce aliasing by mimicking a higher resolution display; 
  5. // multiple sample points are used to determine each pixel's color. This sample shows 
  6. // how the various multisampling techniques supported by your video card affect the 
  7. // scene's rendering. Although multisampling effectively combats aliasing, under 
  8. // particular situations it can introduce visual artifacts of it's own. As illustrated 
  9. // by the sample, centroid sampling seeks to eliminate one common type of multisampling 
  10. // artifact. Support for centroid sampling is supported under Pixel Shader 2.0 in the 
  11. // latest version of the DirectX runtime.
  12. //
  13. // Copyright (c) Microsoft Corporation. All rights reserved.
  14. //--------------------------------------------------------------------------------------
  15. #include "dxstdafx.h"
  16. #include "resource.h"
  17.  
  18. //#define DEBUG_VS   // Uncomment this line to debug vertex shaders 
  19. //#define DEBUG_PS   // Uncomment this line to debug pixel shaders 
  20.  
  21.  
  22. //--------------------------------------------------------------------------------------
  23. // Custom vertex
  24. //--------------------------------------------------------------------------------------
  25. struct Vertex
  26. {
  27.     D3DXVECTOR3 Position;
  28.     D3DCOLOR    Diffuse;
  29.     D3DXVECTOR2 TexCoord;
  30. };
  31.  
  32. D3DVERTEXELEMENT9 VertexElements[] =
  33. {
  34.     { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
  35.     { 0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0 },
  36.     { 0, 16, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
  37.     D3DDECL_END()
  38. };
  39.  
  40.  
  41.  
  42. //--------------------------------------------------------------------------------------
  43. // Global variables
  44. //--------------------------------------------------------------------------------------
  45. const int GUI_WIDTH = 305;
  46.  
  47. char                         g_strActiveTechnique[ MAX_PATH+1 ] = {0};
  48. D3DXMATRIXA16                g_mRotation;
  49.  
  50. IDirect3DVertexDeclaration9* g_pVertexDecl = NULL;
  51. IDirect3DVertexBuffer9*      g_pVBTriangles = NULL;
  52.  
  53. ID3DXMesh*                   g_pMeshSphereHigh = NULL;
  54. ID3DXMesh*                   g_pMeshSphereLow = NULL;
  55.  
  56. ID3DXMesh*                   g_pMeshQuadHigh = NULL;
  57. ID3DXMesh*                   g_pMeshQuadLow = NULL;
  58.  
  59.  
  60. ID3DXFont*                   g_pFont = NULL;         // Font for drawing text
  61. ID3DXSprite*                 g_pTextSprite = NULL;   // Sprite for batching draw text calls
  62. ID3DXEffect*                 g_pEffect = NULL;       // D3DX effect interface
  63. CDXUTDialog                  g_HUD;                  // dialog for standard controls
  64.  
  65. CDXUTDialog                  g_DialogLabels;         // Labels within the current scene
  66.  
  67. bool                         g_bCentroid = false;
  68.  
  69. IDirect3DTexture9*           g_pTriangleTexture = NULL;
  70. IDirect3DTexture9*           g_pCheckerTexture = NULL;
  71.  
  72. DXUTDeviceSettings           g_D3DDeviceSettings;
  73.  
  74.  
  75.  
  76. //--------------------------------------------------------------------------------------
  77. // UI control IDs
  78. //--------------------------------------------------------------------------------------
  79. #define IDC_TOGGLEFULLSCREEN    1
  80. #define IDC_TOGGLEREF           2
  81. #define IDC_CHANGEDEVICE        3
  82. #define IDC_MULTISAMPLE_TYPE    4
  83. #define IDC_MULTISAMPLE_QUALITY 5
  84. #define IDC_CENTROID            6 
  85. #define IDC_FILTERGROUP         7
  86. #define IDC_FILTER_POINT        8
  87. #define IDC_FILTER_LINEAR       9
  88. #define IDC_FILTER_ANISOTROPIC  10
  89. #define IDC_SCENE               11
  90. #define IDC_ROTATIONGROUP       12
  91. #define IDC_ROTATION_RPM        13
  92. #define IDC_RPM                 14
  93. #define IDC_ROTATION_DEGREES    15
  94. #define IDC_DEGREES             16
  95. #define IDC_LABEL0              17
  96. #define IDC_LABEL1              18
  97.  
  98.  
  99.  
  100. //--------------------------------------------------------------------------------------
  101. // Forward declarations 
  102. //--------------------------------------------------------------------------------------
  103. bool    CALLBACK IsDeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, bool bWindowed );
  104. void    CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, const D3DCAPS9* pCaps );
  105. HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc );
  106. HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc );
  107. void    CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime );
  108. void    CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime );
  109. LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing );
  110. void    CALLBACK KeyboardProc( UINT nChar, bool bKeyDown, bool bAltDown  );
  111. void    CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl );
  112. void    CALLBACK OnLostDevice();
  113. void    CALLBACK OnDestroyDevice();
  114.  
  115. void RenderSceneTriangles( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime );
  116. void RenderSceneQuads( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime );
  117. void RenderSceneSpheres( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime );
  118.  
  119. void    InitApp();
  120. HRESULT FillVertexBuffer();
  121. HRESULT LoadMesh( IDirect3DDevice9* pd3dDevice, WCHAR* strFileName, ID3DXMesh** ppMesh );
  122. void    RenderText();
  123.  
  124. HRESULT InitializeUI();
  125. HRESULT OnMultisampleTypeChanged();
  126. HRESULT OnMultisampleQualityChanged();
  127. void AddMultisampleType( D3DMULTISAMPLE_TYPE type );
  128. D3DMULTISAMPLE_TYPE GetSelectedMultisampleType();
  129. void AddMultisampleQuality( DWORD dwQuality );
  130. DWORD GetSelectedMultisampleQuality();
  131. WCHAR* DXUTMultisampleTypeToString(D3DMULTISAMPLE_TYPE MultiSampleType);
  132. CD3DEnumDeviceSettingsCombo* GetCurrentDeviceSettingsCombo();
  133.  
  134.  
  135.  
  136. //--------------------------------------------------------------------------------------
  137. // Entry point to the program. Initializes everything and goes into a message processing 
  138. // loop. Idle time is used to render the scene.
  139. //--------------------------------------------------------------------------------------
  140. INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
  141. {
  142.     // Set the callback functions. These functions allow the sample framework to notify
  143.     // the application about device changes, user input, and windows messages.  The 
  144.     // callbacks are optional so you need only set callbacks for events you're interested 
  145.     // in. However, if you don't handle the device reset/lost callbacks then the sample 
  146.     // framework won't be able to reset your device since the application must first 
  147.     // release all device resources before resetting.  Likewise, if you don't handle the 
  148.     // device created/destroyed callbacks then the sample framework won't be able to 
  149.     // recreate your device resources.
  150.     DXUTSetCallbackDeviceCreated( OnCreateDevice );
  151.     DXUTSetCallbackDeviceReset( OnResetDevice );
  152.     DXUTSetCallbackDeviceLost( OnLostDevice );
  153.     DXUTSetCallbackDeviceDestroyed( OnDestroyDevice );
  154.     DXUTSetCallbackMsgProc( MsgProc );
  155.     DXUTSetCallbackKeyboard( KeyboardProc );
  156.     DXUTSetCallbackFrameRender( OnFrameRender );
  157.     DXUTSetCallbackFrameMove( OnFrameMove );
  158.  
  159.     // Show the cursor and clip it when in full screen
  160.     DXUTSetCursorSettings( true, true );
  161.  
  162.     InitApp();
  163.  
  164.     // Initialize the sample framework and create the desired Win32 window and Direct3D 
  165.     // device for the application. Calling each of these functions is optional, but they
  166.     // allow you to set several options which control the behavior of the framework.
  167.     DXUTInit( true, true, true ); // Parse the command line, handle the default hotkeys, and show msgboxes
  168.     DXUTCreateWindow( L"AntiAlias" );
  169.     DXUTCreateDevice( D3DADAPTER_DEFAULT, true, 640, 480, IsDeviceAcceptable, ModifyDeviceSettings );
  170.  
  171.     // Pass control to the sample framework for handling the message pump and 
  172.     // dispatching render calls. The sample framework will call your FrameMove 
  173.     // and FrameRender callback when there is idle time between handling window messages.
  174.     DXUTMainLoop();
  175.  
  176.     // Perform any application-level cleanup here. Direct3D device resources are released within the
  177.     // appropriate callback functions and therefore don't require any cleanup code here.
  178.  
  179.     return DXUTGetExitCode();
  180. }
  181.  
  182.  
  183. //--------------------------------------------------------------------------------------
  184. // Initialize the app 
  185. //--------------------------------------------------------------------------------------
  186. void InitApp()
  187. {
  188.     // Title font for comboboxes
  189.     g_HUD.SetFont( 1, L"Arial", 14, FW_BOLD );
  190.     CDXUTElement* pElement = g_HUD.GetDefaultElement( DXUT_CONTROL_STATIC, 0 );
  191.     pElement->iFont = 1;
  192.     pElement->dwTextFormat = DT_LEFT | DT_BOTTOM;
  193.  
  194.     // Scene label font
  195.     g_DialogLabels.SetFont( 1, L"Arial", 16, FW_BOLD );
  196.     pElement = g_DialogLabels.GetDefaultElement( DXUT_CONTROL_STATIC, 0 );
  197.     pElement->iFont = 1;
  198.     pElement->FontColor.Init( D3DCOLOR_RGBA( 200, 200, 200, 255 ) );
  199.     pElement->dwTextFormat = DT_LEFT | DT_BOTTOM;
  200.  
  201.     // Initialize dialogs
  202.     int iX = 25, iY = 10;
  203.     g_HUD.SetCallback( OnGUIEvent );  
  204.     g_HUD.AddButton( IDC_TOGGLEFULLSCREEN, L"Toggle full screen", iX + 135, iY, 125, 22 );
  205.     g_HUD.AddButton( IDC_TOGGLEREF, L"Toggle REF (F3)", iX + 135, iY += 24, 125, 22 );
  206.     g_HUD.AddButton( IDC_CHANGEDEVICE, L"Change device (F2)", iX + 135, iY += 24, 125, 22 );
  207.     
  208.     iY += 10;
  209.     g_HUD.AddStatic( -1, L"Scene", iX, iY += 24, 260, 22 );
  210.     g_HUD.AddComboBox( IDC_SCENE, iX, iY += 24, 260, 22 );
  211.     g_HUD.GetComboBox( IDC_SCENE )->AddItem( L"Triangles", NULL );
  212.     g_HUD.GetComboBox( IDC_SCENE )->AddItem( L"Quads", NULL );
  213.     g_HUD.GetComboBox( IDC_SCENE )->AddItem( L"Spheres", NULL );
  214.     
  215.     iY += 10;
  216.     g_HUD.AddStatic( -1, L"Multisample Type", iX, iY += 24, 260, 22 );
  217.     g_HUD.AddComboBox( IDC_MULTISAMPLE_TYPE, iX, iY += 24, 260, 22 );
  218.     g_HUD.AddStatic( -1, L"Multisample Quality", iX, iY += 24, 260, 22 );
  219.     g_HUD.AddComboBox( IDC_MULTISAMPLE_QUALITY, iX, iY += 24, 260, 22 );
  220.     
  221.     iY += 10;
  222.     g_HUD.AddStatic( -1, L"Texture Filtering", iX, iY += 24, 260, 22 );
  223.     
  224.     iY += 10;
  225.     g_HUD.AddCheckBox( IDC_CENTROID, L"Centroid sampling", iX+150, iY + 20, 260, 18, false );
  226.  
  227.     g_HUD.AddRadioButton( IDC_FILTER_POINT, IDC_FILTERGROUP, L"Point", iX+10, iY += 20, 130, 18 );
  228.     g_HUD.AddRadioButton( IDC_FILTER_LINEAR, IDC_FILTERGROUP, L"Linear", iX+10, iY += 20, 130, 18, true );
  229.     g_HUD.AddRadioButton( IDC_FILTER_ANISOTROPIC, IDC_FILTERGROUP, L"Anisotropic", iX+10, iY += 20, 130, 18 );
  230.     
  231.     iY += 10;
  232.     g_HUD.AddStatic( -1, L"Mesh Rotation", iX, iY += 24, 260, 22 );
  233.     
  234.     g_HUD.AddEditBox( IDC_RPM, L"4.0", iX+86, iY + 32, 50, 30 );
  235.     g_HUD.AddRadioButton( IDC_ROTATION_RPM, IDC_ROTATIONGROUP, L"Rotating at                   rpm", iX+10, iY += 38, 300, 18, true );
  236.     g_HUD.AddEditBox( IDC_DEGREES, L"90.0", iX+74, iY + 36, 50, 30 );
  237.     g_HUD.AddRadioButton( IDC_ROTATION_DEGREES, IDC_ROTATIONGROUP, L"Fixed at                   degrees", iX+10, iY += 42, 300, 18 );
  238.  
  239.     // Add labels
  240.     g_DialogLabels.AddStatic( IDC_LABEL0, L"", 0, 0, 200, 25 );
  241.     g_DialogLabels.AddStatic( IDC_LABEL1, L"", 0, 0, 200, 25 );
  242.     
  243.     
  244. }
  245.  
  246.  
  247. //--------------------------------------------------------------------------------------
  248. // Called during device initialization, this code checks the device for some 
  249. // minimum set of capabilities, and rejects those that don't pass by returning false.
  250. //--------------------------------------------------------------------------------------
  251. bool CALLBACK IsDeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, 
  252.                                   D3DFORMAT BackBufferFormat, bool bWindowed )
  253. {
  254.     // No fallback defined by this app, so reject any device that 
  255.     // doesn't support at least ps2.0
  256.     if( pCaps->PixelShaderVersion < D3DPS_VERSION(2,0) )
  257.         return false;
  258.     
  259.     // Skip backbuffer formats that don't support alpha blending
  260.     IDirect3D9* pD3D = DXUTGetD3DObject(); 
  261.     if( FAILED( pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal, pCaps->DeviceType,
  262.                     AdapterFormat, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, 
  263.                     D3DRTYPE_TEXTURE, BackBufferFormat ) ) )
  264.         return false;
  265.  
  266.  
  267.     return true;
  268. }
  269.  
  270.  
  271. //--------------------------------------------------------------------------------------
  272. // This callback function is called immediately before a device is created to allow the 
  273. // application to modify the device settings. The supplied pDeviceSettings parameter 
  274. // contains the settings that the framework has selected for the new device, and the 
  275. // application can make any desired changes directly to this structure.  Note however that 
  276. // the sample framework will not correct invalid device settings so care must be taken 
  277. // to return valid device settings, otherwise IDirect3D9::CreateDevice() will fail.  
  278. //--------------------------------------------------------------------------------------
  279. void CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, const D3DCAPS9* pCaps )
  280. {
  281.     pDeviceSettings->BehaviorFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING;
  282.     
  283.     // This application is designed to work on a pure device by not using 
  284.     // IDirect3D9::Get*() methods, so create a pure device if supported and using HWVP.
  285.     if ((pCaps->DevCaps & D3DDEVCAPS_PUREDEVICE) != 0 && 
  286.         (pDeviceSettings->BehaviorFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING) != 0 )
  287.         pDeviceSettings->BehaviorFlags |= D3DCREATE_PUREDEVICE;
  288.  
  289.     // Debugging vertex shaders requires either REF or software vertex processing 
  290.     // and debugging pixel shaders requires REF.  
  291. #ifdef DEBUG_VS
  292.     if( pDeviceSettings->DeviceType != D3DDEVTYPE_REF )
  293.     {
  294.         pDeviceSettings->BehaviorFlags &= ~D3DCREATE_HARDWARE_VERTEXPROCESSING;
  295.         pDeviceSettings->BehaviorFlags &= ~D3DCREATE_PUREDEVICE;
  296.         pDeviceSettings->BehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
  297.     }
  298. #endif
  299. #ifdef DEBUG_PS
  300.     pDeviceSettings->DeviceType = D3DDEVTYPE_REF;
  301. #endif
  302. }
  303.  
  304.  
  305. //--------------------------------------------------------------------------------------
  306. // This callback function will be called immediately after the Direct3D device has been 
  307. // created, which will happen during application initialization and windowed/full screen 
  308. // toggles. This is the best location to create D3DPOOL_MANAGED resources since these 
  309. // resources need to be reloaded whenever the device is destroyed. Resources created  
  310. // here should be released in the OnDestroyDevice callback. 
  311. //--------------------------------------------------------------------------------------
  312. HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc )
  313. {
  314.     HRESULT hr;
  315.     WCHAR strPath[MAX_PATH];
  316.     
  317.  
  318.     // Create the vertex declaration
  319.     V_RETURN( pd3dDevice->CreateVertexDeclaration( VertexElements, &g_pVertexDecl ) );
  320.  
  321.     // Create the vertex buffer for the triangles / quads
  322.     V_RETURN( pd3dDevice->CreateVertexBuffer( 3 * sizeof(Vertex), D3DUSAGE_WRITEONLY, 
  323.                                               0, D3DPOOL_MANAGED, &g_pVBTriangles, NULL ) );
  324.  
  325.     // Initialize the font
  326.     V_RETURN( D3DXCreateFont( pd3dDevice, 15, 0, FW_BOLD, 1, FALSE, DEFAULT_CHARSET, 
  327.                          OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, 
  328.                          L"Arial", &g_pFont ) );
  329.  
  330.     // Create the spheres
  331.     V_RETURN( DXUTFindDXSDKMediaFileCch( strPath, MAX_PATH, L"spherehigh.x" ) );
  332.     V_RETURN( LoadMesh( pd3dDevice, strPath, &g_pMeshSphereHigh ) );
  333.  
  334.     V_RETURN( DXUTFindDXSDKMediaFileCch( strPath, MAX_PATH, L"spherelow.x" ) );
  335.     V_RETURN( LoadMesh( pd3dDevice, strPath, &g_pMeshSphereLow ) );
  336.  
  337.     V_RETURN( DXUTFindDXSDKMediaFileCch( strPath, MAX_PATH, L"quadhigh.x" ) );
  338.     V_RETURN( LoadMesh( pd3dDevice, strPath, &g_pMeshQuadHigh ) );
  339.  
  340.     V_RETURN( DXUTFindDXSDKMediaFileCch( strPath, MAX_PATH, L"quadlow.x" ) );
  341.     V_RETURN( LoadMesh( pd3dDevice, strPath, &g_pMeshQuadLow ) );
  342.  
  343.     
  344.     // Define DEBUG_VS and/or DEBUG_PS to debug vertex and/or pixel shaders with the 
  345.     // shader debugger. Debugging vertex shaders requires either REF or software vertex 
  346.     // processing, and debugging pixel shaders requires REF.  The 
  347.     // D3DXSHADER_FORCE_*_SOFTWARE_NOOPT flag improves the debug experience in the 
  348.     // shader debugger.  It enables source level debugging, prevents instruction 
  349.     // reordering, prevents dead code elimination, and forces the compiler to compile 
  350.     // against the next higher available software target, which ensures that the 
  351.     // unoptimized shaders do not exceed the shader model limitations.  Setting these 
  352.     // flags will cause slower rendering since the shaders will be unoptimized and 
  353.     // forced into software.  See the DirectX documentation for more information about 
  354.     // using the shader debugger.
  355.     DWORD dwShaderFlags = 0;
  356.     #ifdef DEBUG_VS
  357.         dwShaderFlags |= D3DXSHADER_FORCE_VS_SOFTWARE_NOOPT;
  358.     #endif
  359.     #ifdef DEBUG_PS
  360.         dwShaderFlags |= D3DXSHADER_FORCE_PS_SOFTWARE_NOOPT;
  361.     #endif
  362.  
  363.     // Read the D3DX effect file
  364.     V_RETURN( DXUTFindDXSDKMediaFileCch( strPath, MAX_PATH, L"AntiAlias.fx" ) );
  365.  
  366.     // If this fails, there should be debug output as to 
  367.     // they the .fx file failed to compile
  368.     V_RETURN( D3DXCreateEffectFromFile( pd3dDevice, strPath, NULL, NULL, dwShaderFlags, 
  369.                                         NULL, &g_pEffect, NULL ) );
  370.  
  371.  
  372.     // Load the textures
  373.     V_RETURN( DXUTFindDXSDKMediaFileCch( strPath, MAX_PATH, L"checker.tga" ) );
  374.     V_RETURN( D3DXCreateTextureFromFile( pd3dDevice, strPath, &g_pCheckerTexture ) );
  375.  
  376.     V_RETURN( DXUTFindDXSDKMediaFileCch( strPath, MAX_PATH, L"triangle.tga" ) );
  377.     V_RETURN( D3DXCreateTextureFromFile( pd3dDevice, strPath, &g_pTriangleTexture ) );
  378.  
  379.     return S_OK;
  380. }
  381.  
  382.  
  383. //-----------------------------------------------------------------------------
  384. // Name: LoadMesh()
  385. // Desc: 
  386. //-----------------------------------------------------------------------------
  387. HRESULT LoadMesh( IDirect3DDevice9* pd3dDevice, WCHAR* strFileName, LPD3DXMESH* ppMesh )
  388. {
  389.     LPD3DXMESH pMesh = NULL;
  390.     WCHAR str[MAX_PATH];
  391.     HRESULT hr;
  392.  
  393.     if( ppMesh == NULL )
  394.         return E_INVALIDARG;
  395.  
  396.     DXUTFindDXSDKMediaFileCch( str, MAX_PATH, strFileName );
  397.     hr = D3DXLoadMeshFromX(str, D3DXMESH_MANAGED, 
  398.          pd3dDevice, NULL, NULL, NULL, NULL, &pMesh);
  399.     if( FAILED(hr) || (pMesh == NULL) )
  400.         return hr;
  401.  
  402.     DWORD *rgdwAdjacency = NULL;
  403.  
  404.     // Make sure there are normals which are required for lighting
  405.     if( !(pMesh->GetFVF() & D3DFVF_NORMAL) )
  406.     {
  407.         LPD3DXMESH pTempMesh;
  408.         hr = pMesh->CloneMeshFVF( pMesh->GetOptions(), 
  409.                                   pMesh->GetFVF() | D3DFVF_NORMAL, 
  410.                                   pd3dDevice, &pTempMesh );
  411.         if( FAILED(hr) )
  412.             return hr;
  413.  
  414.         D3DXComputeNormals( pTempMesh, NULL );
  415.  
  416.         SAFE_RELEASE( pMesh );
  417.         pMesh = pTempMesh;
  418.     }
  419.  
  420.     // Optimze the mesh to make it fast for the user's graphics card
  421.     rgdwAdjacency = new DWORD[pMesh->GetNumFaces() * 3];
  422.     if( rgdwAdjacency == NULL )
  423.         return E_OUTOFMEMORY;
  424.     pMesh->ConvertPointRepsToAdjacency(NULL, rgdwAdjacency);
  425.     pMesh->OptimizeInplace(D3DXMESHOPT_VERTEXCACHE, rgdwAdjacency, NULL, NULL, NULL);
  426.     delete []rgdwAdjacency;
  427.  
  428.     *ppMesh = pMesh;
  429.  
  430.     return S_OK;
  431. }
  432.  
  433.  
  434.  
  435. //--------------------------------------------------------------------------------------
  436. // Set the vertices for the triangles scene
  437. //--------------------------------------------------------------------------------------
  438. HRESULT FillVertexBuffer()
  439. {
  440.     HRESULT hr;
  441.  
  442.     Vertex* pVertex = NULL;
  443.     V_RETURN( g_pVBTriangles->Lock( 0, 0, (void**) &pVertex, 0 ) );
  444.     
  445.     float fTexel = 1.0f / 128;
  446.     int   nBorder = 5;
  447.  
  448.     pVertex->Position = D3DXVECTOR3( 1, 1, 0 );
  449.     pVertex->Diffuse = D3DCOLOR_ARGB( 255, 0, 0, 0 );
  450.     pVertex->TexCoord = D3DXVECTOR2( (128 - nBorder) * fTexel, (128 - nBorder) * fTexel );
  451.     pVertex++;
  452.  
  453.     pVertex->Position = D3DXVECTOR3( 0, 1, 0 );
  454.     pVertex->Diffuse = D3DCOLOR_ARGB( 255, 0, 0, 0 );
  455.     pVertex->TexCoord = D3DXVECTOR2( nBorder * fTexel, (128 - nBorder) * fTexel );
  456.     pVertex++;
  457.  
  458.     pVertex->Position = D3DXVECTOR3( 0, 0, 0 );
  459.     pVertex->Diffuse = D3DCOLOR_ARGB( 255, 0, 0, 0 );
  460.     pVertex->TexCoord = D3DXVECTOR2( nBorder * fTexel, nBorder * fTexel );
  461.     pVertex++;
  462.  
  463.     g_pVBTriangles->Unlock();
  464.  
  465.     return S_OK;
  466. }
  467.  
  468.  
  469. //--------------------------------------------------------------------------------------
  470. // Moves the world-space XY plane into screen-space for pixel-perfect perspective
  471. //--------------------------------------------------------------------------------------
  472. HRESULT CalculateViewAndProjection( D3DXMATRIX* pViewOut, D3DXMATRIX* pProjectionOut, float fovy, float zNearOffset, float zFarOffset )
  473. {
  474.     if( pViewOut == NULL ||
  475.         pProjectionOut == NULL )
  476.         return E_INVALIDARG;
  477.  
  478.     // Get back buffer description and determine aspect ratio
  479.     const D3DSURFACE_DESC* pBackBufferSurfaceDesc = DXUTGetBackBufferSurfaceDesc();
  480.     float Width = (float)pBackBufferSurfaceDesc->Width;
  481.     float Height = (float)pBackBufferSurfaceDesc->Height;
  482.     float fAspectRatio = Width/Height;
  483.  
  484.     // Determine the correct Z depth to completely fill the frustum
  485.     float yScale = 1 / tanf( fovy/2 );
  486.     float z = yScale * Height / 2;
  487.     
  488.     // Calculate perspective projection
  489.     D3DXMatrixPerspectiveFovLH( pProjectionOut, fovy, fAspectRatio, z + zNearOffset, z + zFarOffset );
  490.  
  491.     // Initialize the view matrix as a rotation and translation from "screen-coordinates"
  492.     // in world space (the XY plane from the perspective of Z+) to a plane that's centered
  493.     // along Z+
  494.     D3DXMatrixIdentity( pViewOut );
  495.     pViewOut->_22 = -1;
  496.     pViewOut->_33 = -1;
  497.     pViewOut->_41 = -(Width/2);
  498.     pViewOut->_42 = (Height/2);
  499.     pViewOut->_43 = z;
  500.  
  501.     
  502.     return S_OK;
  503. }
  504.  
  505.  
  506. //--------------------------------------------------------------------------------------
  507. // This callback function will be called immediately after the Direct3D device has been 
  508. // reset, which will happen after a lost device scenario. This is the best location to 
  509. // create D3DPOOL_DEFAULT resources since these resources need to be reloaded whenever 
  510. // the device is lost. Resources created here should be released in the OnLostDevice 
  511. // callback. 
  512. //--------------------------------------------------------------------------------------
  513. HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* pd3dDevice, 
  514.                                 const D3DSURFACE_DESC* pBackBufferSurfaceDesc )
  515. {
  516.     HRESULT hr;
  517.  
  518.     if( g_pFont )
  519.         V_RETURN( g_pFont->OnResetDevice() );
  520.     if( g_pEffect )
  521.         V_RETURN( g_pEffect->OnResetDevice() );
  522.  
  523.     V_RETURN( FillVertexBuffer() );
  524.     
  525.     // Create a sprite to help batch calls when drawing many lines of text
  526.     V_RETURN( D3DXCreateSprite( pd3dDevice, &g_pTextSprite ) );
  527.  
  528.     const D3DCOLOR backColor = D3DCOLOR_ARGB(255, 150, 150, 150);
  529.     const D3DCOLOR bottomColor = D3DCOLOR_ARGB(255, 100, 100, 100);
  530.  
  531.     g_HUD.SetBackgroundColors( bottomColor, bottomColor, backColor, backColor );
  532.     g_HUD.SetLocation( pBackBufferSurfaceDesc->Width - GUI_WIDTH, 0 );
  533.     g_HUD.SetSize( GUI_WIDTH, pBackBufferSurfaceDesc->Height );
  534.     
  535.     InitializeUI();
  536.  
  537.     return S_OK;
  538. }
  539.  
  540.  
  541. //--------------------------------------------------------------------------------------
  542. HRESULT InitializeUI()
  543. {
  544.     HRESULT hr;
  545.  
  546.     g_D3DDeviceSettings = DXUTGetDeviceSettings();
  547.     
  548.     CD3DEnumDeviceSettingsCombo* pDeviceSettingsCombo = GetCurrentDeviceSettingsCombo();
  549.     if( pDeviceSettingsCombo == NULL )
  550.         return E_FAIL;
  551.  
  552.     CDXUTComboBox* pMultisampleTypeCombo = g_HUD.GetComboBox( IDC_MULTISAMPLE_TYPE );
  553.     pMultisampleTypeCombo->RemoveAllItems();
  554.  
  555.     for( int ims=0; ims < pDeviceSettingsCombo->multiSampleTypeList.GetSize(); ims++ )
  556.     {
  557.         D3DMULTISAMPLE_TYPE msType = pDeviceSettingsCombo->multiSampleTypeList.GetAt( ims );
  558.  
  559.         bool bConflictFound = false;
  560.         for( int iConf = 0; iConf < pDeviceSettingsCombo->DSMSConflictList.GetSize(); iConf++ )
  561.         {
  562.             CD3DEnumDSMSConflict DSMSConf = pDeviceSettingsCombo->DSMSConflictList.GetAt( iConf );
  563.             if( DSMSConf.DSFormat == g_D3DDeviceSettings.pp.AutoDepthStencilFormat &&
  564.                 DSMSConf.MSType == msType )
  565.             {
  566.                 bConflictFound = true;
  567.                 break;
  568.             }
  569.         }
  570.  
  571.         if( !bConflictFound )
  572.             AddMultisampleType( msType );
  573.     }
  574.  
  575.     CDXUTComboBox* pMultisampleQualityCombo = g_HUD.GetComboBox( IDC_MULTISAMPLE_TYPE );
  576.     pMultisampleQualityCombo->SetSelectedByData( ULongToPtr(g_D3DDeviceSettings.pp.MultiSampleType) );
  577.  
  578.     hr = OnMultisampleTypeChanged();
  579.     if( FAILED(hr) )
  580.         return hr;
  581.  
  582.     return S_OK;
  583. }
  584.  
  585.  
  586. //-------------------------------------------------------------------------------------
  587. CD3DEnumDeviceSettingsCombo* GetCurrentDeviceSettingsCombo()
  588. {
  589.     CD3DEnumeration* pD3DEnum = DXUTGetEnumeration();
  590.     return pD3DEnum->GetDeviceSettingsCombo( g_D3DDeviceSettings.AdapterOrdinal,
  591.                                              g_D3DDeviceSettings.DeviceType,
  592.                                              g_D3DDeviceSettings.AdapterFormat,
  593.                                              g_D3DDeviceSettings.pp.BackBufferFormat,
  594.                                              (g_D3DDeviceSettings.pp.Windowed == TRUE) );
  595. }
  596.  
  597.  
  598. //-------------------------------------------------------------------------------------
  599. HRESULT OnMultisampleTypeChanged()
  600. {
  601.     HRESULT hr = S_OK;
  602.  
  603.     D3DMULTISAMPLE_TYPE multisampleType = GetSelectedMultisampleType();
  604.     g_D3DDeviceSettings.pp.MultiSampleType = multisampleType;
  605.  
  606.     // If multisampling is enabled, then centroid is a meaningful option.
  607.     g_HUD.GetCheckBox( IDC_CENTROID )->SetEnabled( multisampleType != D3DMULTISAMPLE_NONE );
  608.     g_HUD.GetCheckBox( IDC_CENTROID )->SetChecked( multisampleType != D3DMULTISAMPLE_NONE && g_bCentroid );
  609.  
  610.     CD3DEnumDeviceSettingsCombo* pDeviceSettingsCombo = GetCurrentDeviceSettingsCombo();
  611.     if( pDeviceSettingsCombo == NULL )
  612.         return E_FAIL;
  613.  
  614.     DWORD dwMaxQuality = 0;
  615.     for( int iType = 0; iType < pDeviceSettingsCombo->multiSampleTypeList.GetSize(); iType++ )
  616.     {
  617.         D3DMULTISAMPLE_TYPE msType = pDeviceSettingsCombo->multiSampleTypeList.GetAt( iType );
  618.         if( msType == multisampleType )
  619.         {
  620.             dwMaxQuality = pDeviceSettingsCombo->multiSampleQualityList.GetAt( iType );
  621.             break;
  622.         }
  623.     }
  624.    
  625.     // DXUTSETTINGSDLG_MULTISAMPLE_QUALITY
  626.     CDXUTComboBox* pMultisampleQualityCombo = g_HUD.GetComboBox( IDC_MULTISAMPLE_QUALITY );
  627.     pMultisampleQualityCombo->RemoveAllItems();
  628.  
  629.     for( UINT iQuality = 0; iQuality < dwMaxQuality; iQuality++ )
  630.     {
  631.         AddMultisampleQuality( iQuality );
  632.     }
  633.  
  634.     pMultisampleQualityCombo->SetSelectedByData( ULongToPtr(g_D3DDeviceSettings.pp.MultiSampleQuality) );
  635.  
  636.     hr = OnMultisampleQualityChanged();
  637.     if( FAILED(hr) )
  638.         return hr;
  639.  
  640.     return S_OK;
  641. }
  642.  
  643.  
  644. //-------------------------------------------------------------------------------------
  645. HRESULT OnMultisampleQualityChanged()
  646. {
  647.     g_D3DDeviceSettings.pp.MultiSampleQuality = GetSelectedMultisampleQuality();
  648.     
  649.     // Change the device if current settings don't match the UI settings
  650.     DXUTDeviceSettings curDeviceSettings = DXUTGetDeviceSettings();
  651.     if( curDeviceSettings.pp.MultiSampleQuality != g_D3DDeviceSettings.pp.MultiSampleQuality ||
  652.         curDeviceSettings.pp.MultiSampleType != g_D3DDeviceSettings.pp.MultiSampleType )
  653.     {
  654.         if( g_D3DDeviceSettings.pp.MultiSampleType != D3DMULTISAMPLE_NONE )
  655.             g_D3DDeviceSettings.pp.Flags &= ~D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
  656.  
  657.         DXUTCreateDeviceFromSettings( &g_D3DDeviceSettings );
  658.     }
  659.  
  660.     return S_OK;
  661. }
  662.  
  663. //-------------------------------------------------------------------------------------
  664. void AddMultisampleType( D3DMULTISAMPLE_TYPE type )
  665. {
  666.     CDXUTComboBox* pComboBox = g_HUD.GetComboBox( IDC_MULTISAMPLE_TYPE );
  667.     
  668.     if( !pComboBox->ContainsItem( DXUTMultisampleTypeToString(type) ) )
  669.         pComboBox->AddItem( DXUTMultisampleTypeToString(type), ULongToPtr(type) );
  670. }
  671.  
  672.  
  673. //-------------------------------------------------------------------------------------
  674. D3DMULTISAMPLE_TYPE GetSelectedMultisampleType()
  675. {
  676.     CDXUTComboBox* pComboBox = g_HUD.GetComboBox( IDC_MULTISAMPLE_TYPE );
  677.     
  678.     return (D3DMULTISAMPLE_TYPE) PtrToUlong( pComboBox->GetSelectedData() ); 
  679. }
  680.  
  681.  
  682. //-------------------------------------------------------------------------------------
  683. void AddMultisampleQuality( DWORD dwQuality )
  684. {
  685.     CDXUTComboBox* pComboBox = g_HUD.GetComboBox( IDC_MULTISAMPLE_QUALITY );
  686.         
  687.     WCHAR strQuality[50];
  688.     _snwprintf( strQuality, 50, L"%d", dwQuality );
  689.     strQuality[49] = 0;
  690.  
  691.     if( !pComboBox->ContainsItem( strQuality ) )
  692.         pComboBox->AddItem( strQuality, ULongToPtr(dwQuality) );
  693. }
  694.  
  695.  
  696. //-------------------------------------------------------------------------------------
  697. DWORD GetSelectedMultisampleQuality()
  698. {
  699.     CDXUTComboBox* pComboBox = g_HUD.GetComboBox( IDC_MULTISAMPLE_QUALITY );
  700.     
  701.     return PtrToUlong( pComboBox->GetSelectedData() ); 
  702. }
  703.  
  704.  
  705. //--------------------------------------------------------------------------------------
  706. // This callback function will be called once at the beginning of every frame. This is the
  707. // best location for your application to handle updates to the scene, but is not 
  708. // intended to contain actual rendering calls, which should instead be placed in the 
  709. // OnFrameRender callback.  
  710. //--------------------------------------------------------------------------------------
  711. void CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime )
  712. {
  713. }
  714.  
  715.  
  716. //--------------------------------------------------------------------------------------
  717. // This callback function will be called at the end of every frame to perform all the 
  718. // rendering calls for the scene, and it will also be called if the window needs to be 
  719. // repainted. After this function has returned, the sample framework will call 
  720. // IDirect3DDevice9::Present to display the contents of the next buffer in the swap chain
  721. //--------------------------------------------------------------------------------------
  722. void CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime )
  723. {
  724.     HRESULT hr;
  725.     
  726.     // Determine the active technique from the UI settings
  727.     strcpy( g_strActiveTechnique, "Texture" );
  728.  
  729.     if( g_HUD.GetRadioButton( IDC_FILTER_POINT )->GetChecked() )
  730.         strcat( g_strActiveTechnique, "Point" );
  731.     else if( g_HUD.GetRadioButton( IDC_FILTER_LINEAR )->GetChecked() )
  732.         strcat( g_strActiveTechnique, "Linear" );
  733.     else if( g_HUD.GetRadioButton( IDC_FILTER_ANISOTROPIC )->GetChecked() )
  734.         strcat( g_strActiveTechnique, "Anisotropic" );
  735.     else
  736.         return; //error
  737.  
  738.     if( g_HUD.GetCheckBox( IDC_CENTROID )->GetChecked() )
  739.         strcat( g_strActiveTechnique, "Centroid" );
  740.  
  741.     // Get the current rotation matrix
  742.     if( g_HUD.GetRadioButton( IDC_ROTATION_RPM )->GetChecked() )
  743.     {
  744.         float fRotate = (float) _wtof( g_HUD.GetEditBox( IDC_RPM )->GetText() );
  745.         D3DXMatrixRotationY( &g_mRotation, ((float)fTime * 2.0f * D3DX_PI * fRotate) / (60.0f) );
  746.     }
  747.     else if( g_HUD.GetRadioButton( IDC_ROTATION_DEGREES )->GetChecked() )
  748.     {
  749.         float fRotate = (float) _wtof( g_HUD.GetEditBox( IDC_DEGREES )->GetText() );
  750.         D3DXMatrixRotationY( &g_mRotation, fRotate * (D3DX_PI / 180.0f) );
  751.     }
  752.  
  753.     // Clear the render target and the zbuffer 
  754.     V( pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0, 255, 255, 255), 1.0f, 0) );
  755.     
  756.  
  757.     // Render the scene
  758.     if( SUCCEEDED( pd3dDevice->BeginScene() ) )
  759.     {
  760.         V( pd3dDevice->SetStreamSource( 0, g_pVBTriangles, 0, sizeof(Vertex) ) );
  761.         V( pd3dDevice->SetVertexDeclaration( g_pVertexDecl ) );
  762.  
  763.         DXUTComboBoxItem* pSelectedItem = g_HUD.GetComboBox( IDC_SCENE )->GetSelectedItem();
  764.         
  765.         if( 0 == lstrcmp( L"Triangles", pSelectedItem->strText ) )
  766.             RenderSceneTriangles( pd3dDevice, fTime, fElapsedTime );
  767.         else if( 0 == lstrcmp( L"Quads", pSelectedItem->strText ) )
  768.             RenderSceneQuads( pd3dDevice, fTime, fElapsedTime );
  769.         else if( 0 == lstrcmp( L"Spheres", pSelectedItem->strText ) )
  770.             RenderSceneSpheres( pd3dDevice, fTime, fElapsedTime );
  771.  
  772.         
  773.         
  774.         DXUT_BeginPerfEvent( DXUT_PERFEVENTCOLOR, L"HUD / Stats" ); // These events are to help PIX identify what the code is doing
  775.         RenderText();
  776.         V( g_HUD.OnRender( fElapsedTime ) );
  777.         V( g_DialogLabels.OnRender( fElapsedTime ) );
  778.         DXUT_EndPerfEvent();
  779.  
  780.         V( pd3dDevice->EndScene() );
  781.     }
  782.  
  783.  
  784. }
  785.  
  786.  
  787. //-------------------------------------------------------------------------------------
  788. void RenderSceneTriangles( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime )
  789. {
  790.     HRESULT hr;
  791.  
  792.     D3DXMATRIXA16 mWorld;
  793.     D3DXMATRIXA16 mView;
  794.     D3DXMATRIXA16 mProjection;
  795.     D3DXMATRIXA16 mWorldViewProjection;
  796.     D3DXMATRIXA16 mRotation;
  797.     D3DXMATRIXA16 mScaling;
  798.     D3DXMATRIXA16 mTranslation;
  799.  
  800.     CalculateViewAndProjection( &mView, &mProjection, D3DX_PI/4, -100, 100 );
  801.  
  802.     // Place labels within the scene
  803.     g_DialogLabels.GetStatic( IDC_LABEL0 )->SetLocation( 25, 75 );
  804.     g_DialogLabels.GetStatic( IDC_LABEL0 )->SetText( L"Solid Color Fill" );
  805.  
  806.     g_DialogLabels.GetStatic( IDC_LABEL1 )->SetLocation( 175, 75 );
  807.     g_DialogLabels.GetStatic( IDC_LABEL1 )->SetText( L"Texturing Artifacts" );
  808.  
  809.     for( int iTriangle=0; iTriangle < 4; iTriangle++ )
  810.     {
  811.         switch( iTriangle )
  812.         {
  813.             case 0:
  814.                 D3DXMatrixIdentity( &mRotation );
  815.                 D3DXMatrixTranslation( &mTranslation, 75.0f +0.1f, 125.0f -0.5f, 0 );
  816.                 V( g_pEffect->SetTechnique( "Color" ) );
  817.                 break;
  818.  
  819.             case 1:
  820.                 mRotation = g_mRotation;
  821.                 D3DXMatrixTranslation( &mTranslation, 75.0f +0.1f, 275.0f -0.5f, 0 );
  822.                 V( g_pEffect->SetTechnique( "Color" ) );
  823.                 break;
  824.         
  825.             case 2:
  826.                 D3DXMatrixIdentity( &mRotation );
  827.                 D3DXMatrixTranslation( &mTranslation, 225.0f +0.1f, 125.0f -0.5f, 0 );
  828.                 V( g_pEffect->SetTechnique( g_strActiveTechnique ) );
  829.                 break;
  830.  
  831.             case 3:
  832.                 mRotation = g_mRotation;
  833.                 D3DXMatrixTranslation( &mTranslation, 225.0f +0.1f, 275.0f -0.5f, 0 );
  834.                 V( g_pEffect->SetTechnique( g_strActiveTechnique ) );
  835.                 break;
  836.         }
  837.  
  838.         const float Width = 40;
  839.         const float Height = 100;
  840.     
  841.         D3DXMatrixScaling( &mScaling, Width, Height, 1 );
  842.         mWorld = mScaling * mRotation * mTranslation;
  843.         mWorldViewProjection = mWorld * mView * mProjection;
  844.         
  845.         V( g_pEffect->SetMatrix( "g_mWorldViewProjection", &mWorldViewProjection ) );
  846.         V( g_pEffect->SetTexture( "g_tDiffuse", g_pTriangleTexture ) );
  847.         
  848.  
  849.         UINT NumPasses;
  850.         V( g_pEffect->Begin( &NumPasses, 0 ) );
  851.  
  852.         for( UINT iPass=0; iPass < NumPasses; iPass++ )
  853.         {
  854.             V( g_pEffect->BeginPass( iPass ) );
  855.  
  856.             V( pd3dDevice->DrawPrimitive( D3DPT_TRIANGLEFAN, 0, 1 ) );
  857.  
  858.             V( g_pEffect->EndPass() );
  859.         }
  860.  
  861.         V( g_pEffect->End() );
  862.     }
  863. }
  864.  
  865.  
  866. //-------------------------------------------------------------------------------------
  867. void RenderSceneQuads( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime )
  868. {
  869.     HRESULT hr;
  870.  
  871.     D3DXMATRIXA16 mWorld;
  872.     D3DXMATRIXA16 mView;
  873.     D3DXMATRIXA16 mProjection;
  874.     D3DXMATRIXA16 mWorldViewProjection;
  875.     D3DXMATRIXA16 mScaling;
  876.     D3DXMATRIXA16 mTranslation;
  877.  
  878.     const D3DSURFACE_DESC* pDesc = DXUTGetBackBufferSurfaceDesc();
  879.     const float totalWidth = (float)pDesc->Width - GUI_WIDTH;
  880.     const float radius = .2f * totalWidth;
  881.  
  882.     // Place labels within the scene
  883.     g_DialogLabels.GetStatic( IDC_LABEL0 )->SetLocation( (int)( .25f * totalWidth - 50 ), (int)( pDesc->Height / 2.0f - radius - 50 ) );
  884.     g_DialogLabels.GetStatic( IDC_LABEL0 )->SetText( L"2 Triangles" );
  885.  
  886.     g_DialogLabels.GetStatic( IDC_LABEL1 )->SetLocation( (int)( .75f * totalWidth - 50 ), (int)( pDesc->Height / 2.0f - radius - 50 ) );
  887.     g_DialogLabels.GetStatic( IDC_LABEL1 )->SetText( L"8192 Triangles" );
  888.  
  889.     CalculateViewAndProjection( &mView, &mProjection, D3DX_PI/4, -300, 300 );
  890.     
  891.     V( g_pEffect->SetTechnique( g_strActiveTechnique ) );            
  892.     V( g_pEffect->SetTexture( "g_tDiffuse", g_pCheckerTexture ) );
  893.             
  894.     for( int iQuad=0; iQuad < 2; iQuad++ )
  895.     {
  896.         ID3DXMesh* pMesh = NULL;
  897.  
  898.         switch( iQuad )
  899.         {
  900.             case 0:
  901.                 D3DXMatrixTranslation( &mTranslation, .25f * totalWidth, pDesc->Height / 2.0f, 0 );
  902.                 pMesh = g_pMeshQuadLow;
  903.                 break;
  904.  
  905.             case 1:
  906.                 D3DXMatrixTranslation( &mTranslation, .75f * totalWidth, pDesc->Height / 2.0f, 0 );
  907.                 pMesh = g_pMeshQuadHigh;
  908.                 break;
  909.         }
  910.  
  911.         D3DXMatrixScaling( &mScaling, 2*radius, 2*radius, 2*radius );
  912.         mWorld = mScaling * g_mRotation * mTranslation;
  913.         mWorldViewProjection = mWorld * mView * mProjection;
  914.  
  915.         V( g_pEffect->SetMatrix( "g_mWorldViewProjection", &mWorldViewProjection ) );
  916.         
  917.         UINT NumPasses;
  918.         V( g_pEffect->Begin( &NumPasses, 0 ) );
  919.  
  920.         for( UINT iPass=0; iPass < NumPasses; iPass++ )
  921.         {
  922.             V( g_pEffect->BeginPass( iPass ) );
  923.  
  924.             V( pMesh->DrawSubset( 0 ) );
  925.  
  926.             V( g_pEffect->EndPass() );
  927.         }
  928.  
  929.         V( g_pEffect->End() );
  930.     }
  931. }
  932.  
  933.  
  934. //-------------------------------------------------------------------------------------
  935. void RenderSceneSpheres( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime )
  936. {
  937.     HRESULT hr;
  938.  
  939.     D3DXMATRIXA16 mWorld;
  940.     D3DXMATRIXA16 mView;
  941.     D3DXMATRIXA16 mProjection;
  942.     D3DXMATRIXA16 mWorldViewProjection;
  943.     D3DXMATRIXA16 mScaling;
  944.     D3DXMATRIXA16 mTranslation;
  945.  
  946.     const D3DSURFACE_DESC* pDesc = DXUTGetBackBufferSurfaceDesc();
  947.     const float totalWidth = (float)pDesc->Width - GUI_WIDTH;
  948.     const float radius = .2f * totalWidth;
  949.  
  950.     // Place labels within the scene
  951.     g_DialogLabels.GetStatic( IDC_LABEL0 )->SetLocation( (int)( .25f * totalWidth - 50 ), (int)( pDesc->Height / 2.0f - radius - 50 ) );
  952.     g_DialogLabels.GetStatic( IDC_LABEL0 )->SetText( L"180 Triangles" );
  953.  
  954.     g_DialogLabels.GetStatic( IDC_LABEL1 )->SetLocation( (int)( .75f * totalWidth - 50 ), (int)( pDesc->Height / 2.0f - radius - 50 ) );
  955.     g_DialogLabels.GetStatic( IDC_LABEL1 )->SetText( L"8064 Triangles" );
  956.  
  957.     CalculateViewAndProjection( &mView, &mProjection, D3DX_PI/4, -300, 300 );
  958.     
  959.     V( g_pEffect->SetTechnique( g_strActiveTechnique ) );            
  960.     V( g_pEffect->SetTexture( "g_tDiffuse", g_pCheckerTexture ) );
  961.             
  962.     for( int iSphere=0; iSphere < 2; iSphere++ )
  963.     {
  964.         ID3DXMesh* pMesh = NULL;
  965.  
  966.         switch( iSphere )
  967.         {
  968.             case 0:
  969.                 D3DXMatrixTranslation( &mTranslation, .25f * totalWidth, pDesc->Height / 2.0f, 0 );
  970.                 pMesh = g_pMeshSphereLow;
  971.                 break;
  972.  
  973.             case 1:
  974.                 D3DXMatrixTranslation( &mTranslation, .75f * totalWidth, pDesc->Height / 2.0f, 0 );
  975.                 pMesh = g_pMeshSphereHigh;
  976.                 break;
  977.         }
  978.  
  979.         D3DXMatrixScaling( &mScaling, radius, radius, radius );
  980.         mWorld = mScaling * g_mRotation * mTranslation;
  981.         mWorldViewProjection = mWorld * mView * mProjection;
  982.  
  983.         V( g_pEffect->SetMatrix( "g_mWorldViewProjection", &mWorldViewProjection ) );
  984.         
  985.         UINT NumPasses;
  986.         V( g_pEffect->Begin( &NumPasses, 0 ) );
  987.  
  988.         for( UINT iPass=0; iPass < NumPasses; iPass++ )
  989.         {
  990.             V( g_pEffect->BeginPass( iPass ) );
  991.  
  992.             V( pMesh->DrawSubset( 0 ) );
  993.  
  994.             V( g_pEffect->EndPass() );
  995.         }
  996.  
  997.         V( g_pEffect->End() );
  998.     }
  999. }
  1000.  
  1001.  
  1002. //--------------------------------------------------------------------------------------
  1003. // Render the help and statistics text. This function uses the ID3DXFont interface for 
  1004. // efficient text rendering.
  1005. //--------------------------------------------------------------------------------------
  1006. void RenderText()
  1007. {
  1008.     // The helper object simply helps keep track of text position, and color
  1009.     // and then it calls pFont->DrawText( m_pSprite, strMsg, -1, &rc, DT_NOCLIP, m_clr );
  1010.     // If NULL is passed in as the sprite object, then it will work however the 
  1011.     // pFont->DrawText() will not be batched together.  Batching calls will improves performance.
  1012.     CDXUTTextHelper txtHelper( g_pFont, g_pTextSprite, 15 );
  1013.  
  1014.     // Output statistics
  1015.     txtHelper.Begin();
  1016.     txtHelper.SetInsertionPos( 5, 5 );
  1017.     txtHelper.SetForegroundColor( D3DXCOLOR( 0.3f, 0.3f, 0.7f, 1.0f ) );
  1018.     txtHelper.DrawTextLine( DXUTGetFrameStats() );
  1019.     txtHelper.DrawTextLine( DXUTGetDeviceStats() );
  1020.  
  1021.     txtHelper.SetForegroundColor( D3DXCOLOR( 0.4f, 0.4f, 0.6f, 1.0f ) );
  1022.     txtHelper.DrawTextLine( L"Please see the AntiAlias documentation" );
  1023.     
  1024.    
  1025.     txtHelper.End();
  1026. }
  1027.  
  1028.  
  1029. //--------------------------------------------------------------------------------------
  1030. // Before handling window messages, the sample framework passes incoming windows 
  1031. // messages to the application through this callback function. If the application sets 
  1032. // *pbNoFurtherProcessing to TRUE, then the sample framework will not process this message.
  1033. //--------------------------------------------------------------------------------------
  1034. LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing )
  1035. {
  1036.     // Give the dialogs a chance to handle the message first
  1037.     *pbNoFurtherProcessing = g_HUD.MsgProc( hWnd, uMsg, wParam, lParam );
  1038.     if( *pbNoFurtherProcessing )
  1039.         return 0;
  1040.  
  1041.     return 0;
  1042. }
  1043.  
  1044.  
  1045. //--------------------------------------------------------------------------------------
  1046. // As a convenience, the sample framework inspects the incoming windows messages for
  1047. // keystroke messages and decodes the message parameters to pass relevant keyboard
  1048. // messages to the application.  The framework does not remove the underlying keystroke 
  1049. // messages, which are still passed to the application's MsgProc callback.
  1050. //--------------------------------------------------------------------------------------
  1051. void CALLBACK KeyboardProc( UINT nChar, bool bKeyDown, bool bAltDown )
  1052. {
  1053. }
  1054.  
  1055.  
  1056. //--------------------------------------------------------------------------------------
  1057. // Handles the GUI events
  1058. //--------------------------------------------------------------------------------------
  1059. void CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl )
  1060. {
  1061.     switch( nControlID )
  1062.     {
  1063.         case IDC_TOGGLEFULLSCREEN:      DXUTToggleFullScreen(); break;
  1064.         case IDC_TOGGLEREF:             DXUTToggleREF(); break;
  1065.         case IDC_CHANGEDEVICE:          DXUTSetShowSettingsDialog( !DXUTGetShowSettingsDialog() ); break;
  1066.         case IDC_MULTISAMPLE_TYPE:      OnMultisampleTypeChanged(); break;
  1067.         case IDC_MULTISAMPLE_QUALITY:   OnMultisampleQualityChanged(); break;
  1068.         case IDC_CENTROID:              g_bCentroid = ((CDXUTCheckBox*)pControl)->GetChecked(); break;
  1069.     }
  1070. }
  1071.  
  1072.  
  1073. //--------------------------------------------------------------------------------------
  1074. // This callback function will be called immediately after the Direct3D device has 
  1075. // entered a lost state and before IDirect3DDevice9::Reset is called. Resources created
  1076. // in the OnResetDevice callback should be released here, which generally includes all 
  1077. // D3DPOOL_DEFAULT resources. See the "Lost Devices" section of the documentation for 
  1078. // information about lost devices.
  1079. //--------------------------------------------------------------------------------------
  1080. void CALLBACK OnLostDevice()
  1081. {
  1082.     if( g_pFont )
  1083.         g_pFont->OnLostDevice();
  1084.     if( g_pEffect )
  1085.         g_pEffect->OnLostDevice();
  1086.     SAFE_RELEASE( g_pTextSprite ); 
  1087. }
  1088.  
  1089.  
  1090. //--------------------------------------------------------------------------------------
  1091. // This callback function will be called immediately after the Direct3D device has 
  1092. // been destroyed, which generally happens as a result of application termination or 
  1093. // windowed/full screen toggles. Resources created in the OnCreateDevice callback 
  1094. // should be released here, which generally includes all D3DPOOL_MANAGED resources. 
  1095. //--------------------------------------------------------------------------------------
  1096. void CALLBACK OnDestroyDevice()
  1097. {
  1098.     SAFE_RELEASE( g_pEffect );
  1099.     SAFE_RELEASE( g_pFont );
  1100.     SAFE_RELEASE( g_pVertexDecl );
  1101.     SAFE_RELEASE( g_pVBTriangles );
  1102.     SAFE_RELEASE( g_pMeshSphereHigh );
  1103.     SAFE_RELEASE( g_pMeshSphereLow );
  1104.     SAFE_RELEASE( g_pMeshQuadHigh );
  1105.     SAFE_RELEASE( g_pMeshQuadLow );
  1106.     SAFE_RELEASE( g_pCheckerTexture );
  1107.     SAFE_RELEASE( g_pTriangleTexture );
  1108. }
  1109.  
  1110.  
  1111.  
  1112.